package learner.hmm;

import static org.junit.Assert.*;

import java.net.Inet4Address;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Test;

public class AlphaTest {

	@Test
	public void test() {
//		// three states 0.8 this state, 0.2 next state: S1 -> S2 -> S3
//		Map<Integer, Map<Integer, Double>> a = new HashMap<Integer, Map<Integer, Double>>();
//		Map<Integer, Double> s1Transisitions = new HashMap<Integer, Double>();
//		s1Transisitions.put(0, 0.8);
//		s1Transisitions.put(1, 0.2);
		Matrix<Integer, Integer> a = new Matrix<Integer, Integer>();
		a.setElement(0, 0, 0.5);
		a.setElement(0, 1, 0.25);
		a.setElement(0, 2, 0.25);
		
		a.setElement(1, 0, 0.375);
		a.setElement(1, 1, 0.125);
		a.setElement(1, 2, 0.375);
		
		a.setElement(2, 0, 0.125);
		a.setElement(2, 1, 0.625);
		a.setElement(2, 2, 0.375);
		
		Matrix<Integer, MovementVector> b = new Matrix<Integer, MovementVector>();
		b.setElement(0, new MovementVector(0, 0, 0), 0.6);
		b.setElement(0, new MovementVector(0, 1, 0), 0.2);
		b.setElement(0, new MovementVector(1, 0, 0), 0.15);
		b.setElement(0, new MovementVector(1, 1, 0), 0.05);
		
		b.setElement(1, new MovementVector(0, 0, 0), 0.25);
		b.setElement(1, new MovementVector(0, 1, 0), 0.25);
		b.setElement(1, new MovementVector(1, 0, 0), 0.25);
		b.setElement(1, new MovementVector(1, 1, 0), 0.25);

		b.setElement(2, new MovementVector(0, 0, 0), 0.05);
		b.setElement(2, new MovementVector(0, 1, 0), 0.10);
		b.setElement(2, new MovementVector(1, 0, 0), 0.35);
		b.setElement(2, new MovementVector(1, 1, 0), 0.50);

		Map<Integer, Double> pi = new HashMap<Integer, Double>();
		pi.put(0,0.63);
		pi.put(1,0.17);
		pi.put(2,0.20);
		
		
		
		List<MovementVector> movements = new ArrayList<MovementVector>();
		
		movements.add(new MovementVector(0, 0, 0));
		movements.add(new MovementVector(0, 1, 0));
		movements.add(new MovementVector(1, 0, 0));
		movements.add(new MovementVector(1, 1, 0));
		Alpha alpha = new Alpha(a, b, pi, new Movement(movements));
		assertEquals(0.37800002  ,alpha.get(1, 0), 0001);
		assertEquals(0.0425  ,alpha.get(1, 1), 0.0001);
		assertEquals(0.010000001  ,alpha.get(1, 2), 0.0001);
		
		assertEquals(0.041237503  ,alpha.get(2, 0), 0.001);
		assertEquals(0.026640628   ,alpha.get(2, 1), 0.001);
		assertEquals(0.011418751  ,alpha.get(2, 2), 0.001);
		
		AlgorithmValueCalculator calc = new AlgorithmValueCalculator(a, b, pi, new Movement(movements));
		System.out.println(calc.getChanceOnPattern());
//		
//		Map<Integer, Double> s2Transisitions = new HashMap<Integer, Double>();
//		s2Transisitions.put(1, 0.8);
//		s2Transisitions.put(2, 0.2);
//		
//		Map<Integer, Double> s3Transisitions = new HashMap<Integer, Double>();
//		s3Transisitions.put(2, (double)1);
//		
//		a.put(0, s1Transisitions);
//		a.put(1, s2Transisitions);
//		a.put(2, s3Transisitions);
//		
//		Matrix<Integer, Integer> A = new Matrix<Integer, Integer>(a);
//		// b's
//		Map<MovementVector, Map<Integer, Double>> b = new HashMap<MovementVector, Map<Integer, Double>>();
//		MovementVector m11 = new MovementVector(1, 1, 0);
//		Map<Integer, Double> movementProbs1 = new HashMap<Integer, Double>();
//		movementProbs1.put(0, (double)1 /(double) 2);
//		movementProbs1.put(1, (double)1 /(double) 2);
//		movementProbs1.put(2, (double)1 /(double) 2);
//		
//		MovementVector m12 = new MovementVector(1, 2, 1);
//		Map<Integer, Double> movementProbs2 = new HashMap<Integer, Double>();
//		movementProbs2.put(0, (double)1 /(double) 3);
//		movementProbs2.put(1, (double)1 /(double) 3);
//		movementProbs2.put(2, (double)1 /(double) 3);
//		
//		
//		
//		MovementVector m01 = new MovementVector(0, 1, 2);
//		Map<Integer, Double> movementProbs3 = new HashMap<Integer, Double>();
//		movementProbs3.put(0, (double)1 /(double) 6);
//		movementProbs3.put(1, (double)1 /(double) 6);
//		movementProbs3.put(2, (double)1 /(double) 6);
//		
//		b.put(m11, movementProbs1);
//		b.put(m12, movementProbs2);
//		b.put(m01, movementProbs3);
//		
//		Matrix<MovementVector, Integer> B = new Matrix<MovementVector, Integer>(b);
//		
//		// pi
//		Map<Integer, Double> pi = new HashMap<Integer, Double>();
//		pi.put(0,(double)1 /(double) 3);
//		pi.put(1,(double)1 /(double) 3);
//		pi.put(2,(double)1 /(double) 3);
//		
//		// movement
//		List<MovementVector> movementVectors = new ArrayList<MovementVector>();
//		movementVectors.add(m11);
//		movementVectors.add(m11);
//		movementVectors.add(m11);
//		movementVectors.add(m12);
//		movementVectors.add(m12);
//		movementVectors.add(m01);
//		Movement movement = new Movement(movementVectors);
//		
//		Alpha alpha = new Alpha(A,B,pi,movement );
//		Beta beta = new Beta(A,B,movement);
//		for (int k = 1 ; k <=movement.getSize() ; k ++ ) {
//			System.out.println("alpha_k= "+ k + " : " + alpha.get(k,0) + " ; " + alpha.get(k,1) + " ; " + alpha.get(k,2));
//			System.out.println("beta_k= "+ k + " : " + beta.get(k,0) + " ; " + beta.get(k,1) + " ; " + beta.get(k,2));
//		}
//		
//		
//		AlgorithmValueCalculator avc = new AlgorithmValueCalculator(A, B, pi, movement);
//		System.out.println(avc.getPsiForTime(1, 2, 1));
//		assertTrue(true);
	}

}
